package com.talkyun.openx.validator;

import com.talkyun.openx.server.core.AbstractInterceptor;
import com.talkyun.openx.server.core.ServiceFactory;
import com.talkyun.openx.server.core.ServiceRequest;
import com.talkyun.openx.server.impl.SimpleServiceFactory;
import com.talkyun.openx.validator.impl.ValidateHandler;
import com.talkyun.utils.Reflector;
import com.talkyun.utils.json.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ValidateInterceptor extends AbstractInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(ValidateInterceptor.class);
    private ServiceFactory serviceFactory = SimpleServiceFactory.getInstance();
    private ValidateHandler validateHandler = new ValidateHandler();

    @Override
    public void doMessageIn(ServiceRequest sr) {
        Object service = serviceFactory.getService(sr.getMapping());
        Method method = Reflector.getMethod(service.getClass(), sr.getMethod());
        Map<String, Object> args = sr.getArgs();

        List<ValidateMessage> list = new ArrayList<ValidateMessage>(4);
        // TODO cache annotation meta
        Annotation all[] = method.getAnnotations();
        for (Annotation ann : all) {
            String argName = getArgName(ann);
            Object argVal = args.get(argName);
            ValidateMessage vm = validateHandler.handle(ann, argName, argVal);
            if (vm != null) {
                list.add(vm);
            }
        }
        if (!list.isEmpty()) {
            throw new ValidateException(buildValMsg(list));
        }
    }

    private String getArgName(Annotation ann) {
        Class<?> clazz = ann.annotationType();
        return null; // (String) Reflector.invoke(clazz, "field", ann);
    }

    private String buildValMsg(List<ValidateMessage> list) {
        Map<String, Object> msg = new HashMap<String, Object>(4);
        msg.put("code", "00005050");
        msg.put("message", "参数校验错误！");
        msg.put("class", ValidateInterceptor.class.getName());
        msg.put("detail", list);
        return JSON.toJsonString(msg);
    }
}